package xworker.netty.handlers.message;

import io.netty.channel.ChannelHandlerContext;
import xworker.netty.NettySession;
import xworker.lang.executor.Executor;
import xworker.lang.task.TaskManager;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class HandlerExecutor {
    private static final String TAG = HandlerExecutor.class.getName();

    Handler handler;
    Method method;

    public HandlerExecutor(Handler handler, Method method){
        this.handler = handler;
        this.method = method;
    }

    public void execute(final ChannelHandlerContext ctx, final Object msg) throws Exception{
        if(handler.executor()){
            TaskManager.getExecutorService().submit(() -> {
                try{
                    doExecute(ctx, msg);
                }catch(Exception e){
                    Executor.warn(TAG, "Execute handler error, handler=" + handler + ", method=" + method);
                    ctx.fireExceptionCaught(e);
                }
            });
        }else{
            doExecute(ctx, msg);
        }
    }

    private void doExecute(ChannelHandlerContext ctx, Object msg) throws InvocationTargetException, IllegalAccessException {
        int paramsCount = method.getParameterCount();
        if (paramsCount == 3) {
            method.invoke(null, msg, NettySession.getSession(ctx), ctx);
        } else if (paramsCount == 2) {
            method.invoke(null, msg, NettySession.getSession(ctx));
        } else if (paramsCount == 1) {
            method.invoke(null, msg);
        } else {
            ctx.fireExceptionCaught(new RuntimeException("Execute handler error, handler=" + handler + ", method=" + method));
        }
    }
}
